﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace AL100.BankApplication.BLL
{
    /// <summary>
	/// Classe Helper pour les opérations de réflexion.
	/// </summary>
    public static class ReflectionHelper
    {

        #region -- Dynamic Invoke Methods -- 


        /// <summary>
        /// Gets the property value.
        /// </summary>
        /// <typeparam name="T">Property type</typeparam>
        /// <param name="target">The target.</param>
        /// <param name="propertyName">Name of the property.</param>
        /// <returns></returns>
        static public T GetPropertyValue<T>(this object target, string propertyName)
        {
            BindingFlags flags = ReflectionHelper.GetStandardBindings();

            object val = target.GetType().InvokeMember(propertyName,
                                                       flags | BindingFlags.GetProperty,
                                                       null,
                                                       target,
                                                       null);
            return (T)val;
        }


        /// <summary>
        /// Sets the property value.
        /// </summary>
        /// <param name="target">The target.</param>
        /// <param name="propertyName">Name of the property.</param>
        static public void SetPropertyValue<T>(this object target, string propertyName, T propertyValue)
        {
            BindingFlags flags = ReflectionHelper.GetStandardBindings();

            object val = target.GetType().InvokeMember(propertyName,
                                                       flags | BindingFlags.SetProperty,
                                                       null,
                                                       target,
                                                       new object[] { propertyValue });
        }


        /// <summary>
        /// Invokes the method.
        /// </summary>
        /// <typeparam name="T">Return type of the method.</typeparam>
        /// <param name="target">The target.</param>
        /// <param name="methodName">Name of the method.</param>
        /// <param name="args">The method arguments.</param>
        /// <returns></returns>
        static public T InvokeMethod<T>(this object target, string methodName, params object[] args)
        {
            BindingFlags flags = ReflectionHelper.GetStandardBindings();

            object val = target.GetType().InvokeMember(methodName,
                                                       flags | BindingFlags.InvokeMethod,
                                                       null,
                                                       target,
                                                       args);

            return (T)val;
        }

        /// <summary>
        /// Invokes the method.
        /// </summary>
        /// <typeparam name="T">Return type of the method</typeparam>
        /// <param name="target">The target type.</param>
        /// <param name="methodName">Name of the method.</param>
        /// <param name="args">The method arguments.</param>
        /// <returns></returns>
        static public T InvokeMethod<T>(this Type target, string methodName, params object[] args)
        {
            BindingFlags flags = ReflectionHelper.GetStandardBindings();

            object val = target.InvokeMember(methodName,
                                             flags | BindingFlags.InvokeMethod,
                                             null,
                                             target,
                                             args);

            return (T)val;
        }



        #endregion





















        /// <summary>
        /// Renvoie un objet <see cref="BindingFlags"/> incluant les membres (Instance | Static | Public | NonPublic).
        /// </summary>
        /// <returns>Un objet <see cref="BindingFlags"/>.</returns>
        static private BindingFlags GetStandardBindings()
        {
            return BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
        }


    }
}
